<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"></head><body><a
 name="Contents"><h2>Contents</h2></a>

<ul>
<li><a href="#Contents">Contents</a>
</li><li><a href="#Introduction">Introduction</a>
</li><li><a href="#System%20Requirements">System Requirements</a>
</li><li><a href="#Running%20a%20Simulation">Running a Simulation</a>
</li><li><a href="#The%20World">The World</a>
</li><li><a href="#Walls">Walls</a>
</li><li><a href="#Hockey%20Pucks">Hockey Pucks</a>
</li><li><a href="#Lights">Lights</a>
</li><li><a href="#Robots">Robots</a>
</li><li><a href="#Behaviors">Behaviors</a>
	<ul>
	<li><a href="#Anti-moth">Anti-moth</a>
	</li><li><a href="#Avoid">Avoid</a>
	</li><li><a href="#Cruise">Cruise</a>
	</li><li><a href="#Dark-push">Dark-push</a>
	</li><li><a href="#Escape">Escape</a>
	</li><li><a href="#GDR">GDR</a>
	</li><li><a href="#Gizmo">Gizmo</a>
	</li><li><a href="#Home">Home</a>
	</li><li><a href="#London">London</a>
	</li><li><a href="#Remote">Remote</a>
	</li><li><a href="#Stop">Stop</a>
	</li><li><a href="#Wall%20Follow">Wall Follow</a>
	</li><li><a href="#Wander">Wander</a>
	</li></ul>
</li><li><a href="#Tasks">Tasks</a>
	<ul>
	<li><a href="#Collection%20Task">Collection Task</a>
	</li><li><a href="#Gizmo%20Task">Gizmo Task</a>
	</li><li><a href="#London%20Task">London Task</a>
	</li><li><a href="#User%20Control%20Task">User Control Task</a>
	</li></ul>
</li><li><a href="#Simulations">Simulations</a>
	<ul>
	<li><a href="#New%20Simulation">New Simulation</a>
	</li><li><a href="#Collection%20Simulation">Collection Simulation</a>
	</li><li><a href="#Gizmo%20Simulation">Gizmo Simulation</a>
	</li><li><a href="#London%20Simulation">London Simulation</a>
	</li></ul>
</li></ul>

<ul>

<li>
<a name="Introduction">
<h2>Introduction</h2>
</a>

<p>Welcome to BSim, a behavior based robot simulator.  BSim is designed 
to allow users to experiment with behavior based programming techniques 
without requiring access to an actual robot (The B in BSim stands for 
behavior).  BSim enables users to create simple worlds of rigid objects 
and light sources and to program robots to interact with these worlds.  
Various behaviors and tasks are built into the simulator to give users a
 feel for what can be accomplished with behavior-based programming.  The
 simulator is accessible as a Java applet on a web page to permit 
maximum availability of the software.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="System Requirements">
<h2>System Requirements</h2>
</a>

<p>BSim is a Java applet which runs inside your browser.  To use BSim 
you will need an up to data Java Plugin which you can download and 
install from <a href="http://www.java.com/">www.java.com</a>.</p>

<p>The BSim applet is 800 by 600 pixels so you will need to set your 
screen resolution to be at least that in order to see the entire applet 
on the screen.  Larger screen resolutions are recommended.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="Running a Simulation">
<h2>Running a Simulation</h2>
</a>

<p>To run a simulation, just press the <b>Start</b> button on the 
simulator control panel.  Or, you can also repeatedly press the <b>Step</b>
 button to step through the simulation one time step at a time. You can 
stop a running simulation by pressing the <b>Stop </b> button.  To reset
 the simulator to the last time that the <b>Start</b> button was 
pressed, press the <b>Reset</b> button.</p>

<p>Several prearranged simulations can be selected from the <b>Simulations</b>
 menu, or you can build your own simulated worlds, and program your own 
robots to perform tasks in that world.  The simulation can be run in a 
more true to life noisy world, or it can be run in <b>Fantasy Mode</b>. 
 In <b>Fantasy Mode</b>, the robot get exact readings from it's wheel 
encoders and can turn exact angles and move exact distances.  To turn on
 <b>Fantasy Mode</b>, select the <b>Options</b> menu and select the <b>Fantasy
 Mode</b> menu item.  From the same menu you can also set how much 
latency the robot's light sensors have.  To set the latency, again 
select the <b>Options</b> menu and select the <b>Set Latency</b> menu 
item.  Move the slider to set how much latency there should be in the 
world.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="The World">
<h2>The World</h2>
</a>

<p>The world in BSim consists of a two dimensional plane with walls, 
lights, pushable hockey pucks and robots.  To add something to the 
world, click on the corresponding world tool button on the left side of 
the world view.  Click anywhere on the world view to add the selected 
item to the world and simulation.  Solid objects, such as robots, walls 
and hockey pucks, cannot overlap when added to the world, and you will 
see an error dialog appear if you try to do so.  You can reposition any 
object added to the world by dragging the object to a new location.  You
 can also delete objects by selecting the object and then pressing the <b>Delete</b>
 or <b>Backspace</b> keys.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="Walls">
<h2>Walls</h2>
</a>

<p>To add a wall to the world, click the <b>Wall</b> world tool button. 
 To position the wall, first press and hold the mouse button on the 
world view to indicate where one end of the wall should go.  Then drag 
the mouse to the location where the other end of the wall should go and 
then release the mouse button.  As you drag the mouse, the wall will be 
drawn to indicate where it's position would be if the mouse button were 
released.  Once the wall is placed you can move its end points by 
selecting the wall and then moving the position handles at either end of
 the wall.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="Hockey Pucks">
<h2>Hockey Pucks</h2>
</a>

<p>Hockey Pucks are small round objects which can be pushed by other 
moving objects.  A robot can push at most one hockey puck at a time.  To
 add a hockey puck to the world, click on the <b>Hockey Puck</b> world 
tool button.  Then, click on the world view to add the hockey puck to 
the world at the location of the mouse cursor.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="Lights">
<h2>Lights</h2>
</a>

<p>All lights are point sources in BSim.  The lights are at the same 
level as all other solid objects, so any solid object can block a view 
of a light source.  To add a light to the world, click on the <b>Light</b>
 world tool button.  Then, click on the world view to add the light to 
the world at the location of the mouse cursor.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="Robots">
<h2>Robots</h2>
</a>

<p>Robots are what makes BSim fun!  The robots in BSim are circular 
differential drive robots with a bumper, two IR proximity sensors, two 
photo sensors and wheel encoders.  The photo and IR sensors face 
diagonally from the front of the robot at 45 degree angles.</p>

<p>Each robot supports a simple, yet powerful, behavior-based 
programming system which includes a set of primitive behaviors and a 
priority list arbiter.  A robot's program is called a <i>task</i>.  A 
task is a prioritized list of behaviors which all simultaneously compete
 to control the robot.  The arbiter chooses which behavior is 
successful.  You can program each robot by configuring a set of 
behaviors, prioritizing the behaviors for the arbiter, and then loading 
the behaviors into the robot.</p>

<p>To add a robot to the world, click on the <b>Robot</b> world tool 
button.  Then, click on the world view to add the light to the world at 
the location of the mouse cursor.  The robot can be reoriented by 
selecting the robot and then moving the green orientation handle.</p>

<p>The sensor panel on the right side of the world view is immediately 
updated to be the sensor panel of the robot just added.  To view the 
sensor panel for a robot previously added, just click on the robot you 
are interested in.  The sensor panel shows the state of all the robot 
sensors and also a brief history of the behaviors chosen by the robot's 
arbiter.</p>

<p>To program a robot, double click on the robot to make the <b>Robot 
Programmer</b> dialog appear.  On the left side of the <b>Robot 
Programmer</b> are two selectable lists.  The left most list is the 
behaviors list and it contains the list of primitive behaviors that the 
robot supports.  The list on the right side is the task list and it 
contains the behaviors that make up the robot's current task.  A task is
 a prioritized list of configured behaviors that make up the robot's 
program.</p>

<p>You can add a behavior to the current task in any one of three ways. 
 You can either select the behavior from the <b>Behaviors</b> menu, 
double-click the behavior in the behaviors list, or select the behavior 
in the behaviors list and click the <b>Add</b> button.  To remove a 
behavior from the current task either double-click the behavior in the 
behaviors list, or select the behavior in the behaviors list and click 
the <b>Remove</b> button.</p>

<p>You can configure any behavior in the robot's task by selecting the 
behavior in the task list and then changing the behavior's parameters 
which appear on the right side of the <b>Robot Programmer</b>.  To 
change a parameter, click on the parameter's value and then edit the 
value in the text box, or drop down list that appears.  If you edit the 
value in a text box, be sure to hit the Enter button to finish changing 
the value!  The text box will then disappear and the new parameter value
 will be displayed in gray.  You can also use any of a number of ready 
made tasks by selecting a task from the <b>Task</b> menu.  To load the 
current task into the robot, click the <b>Load</b> button.  To leave the
 robot's program unchanged, click the <b>Cancel</b> button.</p>

<p><a href="#Contents">Contents</a></p>


</li><li>
<a name="Behaviors">
<h2>Behaviors</h2>
</a>

<p>The robots in BSim currently support a fixed set of behaviors.  A 
behavior can be configured to act in different ways by setting the 
behavior's parameters.  What follows is the current listing of all 
behaviors and their parameters, although this list is constantly being 
updated to make the robots more flexible and interesting.</p>

<ul>

<li><a name="Anti-moth"><h3>Anti-moth</h3></a>

<p>The <a href="#Anti-moth">Anti-moth</a> behavior is a ballistic 
behavior similar to the <a href="#Escape">Escape</a> behavior.  It 
triggers whenever the total light intensity measured by the robot&#8217;s 
photocells exceeds a threshold.</p>

<dl>
<dt>Backup time:
</dt><dd>The amount of time to backup.
</dd><dt>Forward time:
</dt><dd>The amount of time to go forward.
</dd><dt>Spin:
</dt><dd>The angle to spin in degrees.
</dd><dt>Random:
</dt><dd>The random component to add to the spin angle.
</dd><dt>Threshold:
</dt><dd>The light level at which the robot will perform an <a 
href="#Escape">Escape</a> sequence.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Avoid"><h3>Avoid</h3></a>

<p>The <a href="#Avoid">Avoid</a> behavior (given a positive <i>Gain</i>
 parameter) moves the robot forward and left if the right proximity 
sensor is on, or forward and right if the left proximity sensor is on. 
This tends to make the robot avoid obstacles. If <i>Gain</i> is 
negative, the robot turns toward obstacles. The magnitude of <i>Gain</i>
 determines how tightly the robot arcs.</p>

<dl>
<dt>Gain:
</dt><dd>The sign of <i>Gain</i> determines in which direction and how 
tightly the robot arcs when a proximity sensor is on.
</dd><dt>Speed:
</dt><dd>The speed at which the robot moves forward when avoiding 
obstacles.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Cruise"><h3>Cruise</h3></a>

<p>The <a href="#Cruise">Cruise</a>  behavior drives the wheels at 
constant speeds.  The behavior can try to drive the wheels at any speed,
 positive or negative, but the robot speed will max out at +/- 255.  In 
the general case, the <a href="#Cruise">Cruise</a>  behavior drives the 
robot moves in circular arcs.</p>

<dl>
<dt>Left wheel speed:
</dt><dd>The left wheel speed.
</dd><dt>Right wheel speed:
</dt><dd>The right wheel speed
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Dark-push"><h3>Dark-push</h3></a>

<p>The <a href="#Dark-push">Dark-push</a> behavior is a ballistic 
behavior similar to the <a href="#Escape">Escape</a> behavior.  It 
triggers whenever the robot tries to push something when no light is 
visible.</p>

<dl>
<dt>Backup time:
</dt><dd>The amount of time to backup.
</dd><dt>Forward time:
</dt><dd>The amount of time to go forward.
</dd><dt>Spin:
</dt><dd>The angle to spin in degrees.
</dd><dt>Random:
</dt><dd>The random component to add to the spin angle.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Escape"><h3>Escape</h3></a>

<p>The <a href="#Escape">Escape</a> behavior is a ballistic behavior 
triggered whenever the robot bumps into something.  The behavior is 
performed in three steps: backup for a specified amount of time, spin a 
certain angle, and go forward for a specified amount of time.  A random 
component can be added to the spin angle by setting the <i>Random</i> 
parameter to be non zero.  In general, the spin angle will be <i>Spin</i>
 + <i>Random</i> * 2 * (random() - 0.5) where random() is a function 
that returns a random number between 0 and 1.  The robot will turn in 
the direction which will require the least amount of rotation to end up 
at the desired angle.</p>

<dl>
<dt>Backup time:
</dt><dd>The amount of time to backup.
</dd><dt>Forward time:
</dt><dd>The amount of time to go forward.
</dd><dt>Spin:
</dt><dd>The angle to spin in degrees.
</dd><dt>Random:
</dt><dd>The random component to add to the spin angle.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="GDR"><h3>GDR</h3></a>

<p>The <a href="#GDR">GDR</a>  behavior determines what speeds to set 
the wheels to by applying a linear transformation (a matrix 
multiplication) to a pair of input signals which can be either the IR 
sensors, or the photo sensors.  The transformation is as follows:<br>
<br>
Translation = a11 * left + a21 * right + a31<br>
Rotation = a12 * left + a22 * right + a32<br>
Active = a13 * left + a23 * right + a33<br>
<br>
where Translation is the translational velocity of the robot, Rotation 
is the rotational velocity of the robot, and Active is wether or not <a 
href="#GDR">GDR</a> requests control of the robot.  Left and right are 0
 or 1 if the input signal is the IR sensors, and between 0 and 255 if 
the input signal is the photo sensors.</p>

<dl>
<dt>a11:
</dt><dd>Left translational component.
</dd><dt>a21:
</dt><dd>Right translational component.
</dd><dt>a31:
</dt><dd>Translational offset.
</dd><dt>a12:
</dt><dd>Left rotational component.
</dd><dt>a22:
</dt><dd>Right rotational component.
</dd><dt>a32:
</dt><dd>Rotational offset.
</dd><dt>a13:
</dt><dd>Left active component.
</dd><dt>a23:
</dt><dd>Right active component.
</dd><dt>a33:
</dt><dd>Active offset.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Gizmo"><h3>Gizmo</h3></a>

<p>The <a href="#Gizmo">Gizmo</a> behavior adjusts the robot&#8217;s position 
relative to a light source such that the sensed brightness matches a 
predetermined value. If the light is too dim, the robot drives forward, 
and if the light is too bright, the robot drives backward. The behavior 
drives the robot in a straight path and sets the wheel speeds using a 
proportional controller.</p>

<dl>
<dt>Gain:
</dt><dd>Determines how fast the robot approaches the light.
</dd><dt>Light:
</dt><dd>The light level which <a href="#Gizmo">Gizmo</a> is trying to 
arrive at.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Home"><h3>Home</h3></a>

<p>The <a href="#Home">Home</a> behavior tries to drive the robot toward
 a light source.  <a href="#Home">Home</a> uses a proportional 
controller to home on a light source whenever the robot&#8217;s photo sensors 
see light. The robot homes on the light by pivoting in the direction of 
the light and then moving forward a step. The robot determines the 
direction to the light by calculating the difference between the two 
photo sensor measurements.</p>

<dl>
<dt>Gain:
</dt><dd>Determines how rapidly the robot turns toward the light.
</dd><dt>Speed:
</dt><dd>Determines how fast the robot moves.
</dd><dt>Home when pushing:
</dt><dd>When set to true, the behavior will only be triggered when the 
robot is pushing something.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="London"><h3>London</h3></a>

<p>The <a href="#London">London</a>  behavior moves the robot in a 
rectangular path. <a href="#London">London</a> is able to perform 
precise 90-degree turns because its implementation is carefully tuned to
 the timing of the simulator. However, if the simulator is not operating
 in <b>Fantasy Mode</b>, the <a href="#London">London</a> behavior will 
gradually wander away from the desired path.</p>

<dl>
<dt>Height:
</dt><dd>The number of seconds that the robot moves vertically.
</dd><dt>Width:
</dt><dd>The number of seconds that the robot moves horizontally.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Remote"><h3>Remote</h3></a>

<p>The <a href="#Remote">Remote</a> behavior responds to commands from a
 user-controllable joystick panel which is made visible once the 
simulator starts. This control can drive the robot forward, backward, 
and pivot the robot left and right.</p>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Stop"><h3>Stop</h3></a>

<p>The <a href="#Stop">Stop</a> behavior sets the wheel speeds to zero.</p>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Wall Follow"><h3>Wall Follow</h3></a>

<p>The <a href="#Wall%20Follow">Wall Follow</a> behavior uses the 
robot's left and right proximity sensors to perform wall following.  The
 <a href="#Wall%20Follow">Wall Follow</a> behavior begins in a START 
state, and remains there until either the left or right proximity sensor
 detects an object. Whenever the robot detects an object on the left, 
the behavior enters a LEFT state that moves the robot forward and to the
 right. If the robot detects an object on the right, the behavior enters
 a RIGHT state.  In this state, the robot moves forward and to the left.
  From the LEFT and RIGHT states, once the robot has veered so
far away that its proximity sensors are not detecting anything, the 
robot enters a LEFT_LOST or RIGHT_LOST state. The LEFT_LOST state moves 
the robot forward and left in an effort to search for the wall and the 
RIGHT_LOST state moves the robot forward and right. This continues until
 either a proximity sensor is triggered (transitioning the behavior back
 to the LEFT or RIGHT state), or the lost states time out and the 
behavior goes back to the START state. If at any time the last chosen 
behavior was not the wall-following behavior, the behavior immediately
resets to the START state.</p>

<dl>
<dt>Found speed:
</dt><dd>The speed at which the robot moves when it has found a wall.
</dd><dt>Lost speed:
</dt><dd>The speed at which the robot moves when it has lost the wall.
</dd><dt>Give up time:
</dt><dd>The amount of time the robot will search for a wall before 
giving up.
</dd><dt>Turn speed:
</dt><dd>The sped at which the robot turns when searching for a wall.
</dd></dl>

<p><a href="#Contents">Contents</a></p>

</li><li><a name="Wander"><h3>Wander</h3></a>

<p>The <a href="#Wander">Wander</a> behavior causes the robot to meander
 aimlessly.</p>

<dl>
<dt>Speed:
</dt><dd>How fast the robot wanders.
</dd></dl>

</li></ul>


</li><li>
<a name="Tasks">
<h2>Tasks</h2>
</a>

<p>Tasks are sets of behaviors which have been configured and 
prioritized to perform some sort of useful function.  BSim contains a 
number of predefined tasks which you can experiment with or you can 
create your own.  The predefined tasks are accessible from the <b>Tasks</b>
 menu in the <b>Robot Programmer</b> and are described in this section.</p>

<ul>

<li><a name="Collection Task"><h3>Collection</h3></a>

<p>The <a href="#Collection%20Task">Collection Task</a> brings scattered
 pucks to a light source. The <a href="#Collection%20Task">Collection 
Task</a> uses behaviors <a href="#Escape">Escape</a>, <a 
href="#Dark-push">Dark-push</a>, <a href="#Anit-moth">Anti-moth</a>, <a 
href="#Avoid">Avoid</a>, <a href="#Home">Home</a>, and <a href="#Cruise">Cruise</a>
 in order of decreasing priority. Under the control of <a href="#Cruise">Cruise</a>,
 the robot drives straight until it comes to an object. If the IR 
sensors detect the object, the robot turns toward the object. Upon 
colliding with the object, one of two things occurs. If the object is an
 immovable wall, then <a href="#Escape">Escape</a> takes control and 
drives the robot away from the object. If the object is a movable puck, 
then the robot begins to push the puck. If the robot is pointed away 
from the light source, <a href="#Dark-push">Dark-push</a> becomes active
 and forces the robot to turn away, abandoning the puck. If a light 
source is visible to the robot, then <a href="#Home">Home</a> becomes 
active and the robot homes on the light. When the robot approaches too 
close to the light and the apparent brightness becomes too great, the <a
 href="#Anit-moth">Anti-moth</a> behavior triggers turning the robot 
away from the light.</p>

<a href="#Contents">Contents</a>

</li><li><a name="Gizmo Task"><h3>Gizmo</h3></a>

<p>The <a href="#Gizmo%20Task">Gizmo Task</a> loads the <a href="#Gizmo">Gizmo</a>
 behavior. This behavior actively positions the robot a set distance 
from a light source. The task also includes the <a href="#Escape">Escape</a>
 behavior for robustness.</p>

<a href="#Contents">Contents</a>

</li><li><a name="London Task"><h3>London</h3></a>

<p>The <a href="#London%20Task">London Task</a> loads the <a 
href="#London">London</a> behavior, which drives the robot in a square 
path. The <a href="#Escape">Escape</a> behavior is not added here, in 
order to show how open loop control can fail, allowing the robot to 
wander from its path and become stuck.</p>

<a href="#Contents">Contents</a>

</li><li><a name="User Control Task"><h3>User Control</h3></a>

<p>The <a href="#User%20Control%20Task">User Control Task</a> contains 
the <a href="#Remote">Remote</a> behavior which allows you to manual 
drive the robot.</p>

<a href="#Contents">Contents</a>

</li></ul>


</li><li>
<a name="Simulations">
<h2>Simulations</h2>
</a>

<p>Simulations are complete worlds with programmed robots and objects 
which can be loaded and run.  All available predefined simulations are 
accessible from the <b>Simulations</b> menu in the main BSim window.  
The simulations are described below.</p>
<ul>

<li><a name="New Simulation"><h3>New Simulation</h3></a>

<p>To start your own simulation select <b>New</b> from the <b>Simulations</b>
 menu.  The world will be cleared of all objects.</p>

<a href="#Contents">Contents</a>

</li><li><a name="Collection Simulation"><h3>Collection Simulation</h3></a>

<p>The <a href="#Collection%20Simulation">Collection Simulation</a> 
demonstrates the <a href="#Collection%20Task">Collection Task</a>. A 
robot is positioned in a room with scattered pucks and a central light 
source. As the simulation runs, the robot moves the pucks to the 
vicinity of the light source.</p>

<a href="#Contents">Contents</a>

</li><li><a name="Gizmo Simulation"><h3>Gizmo Simulation</h3></a>

<p>The <a href="#Gizmo%20Simulation">Gizmo Simulation</a> demonstrates 
proportional control using the <a href="#Gizmo%20Task">Gizmo Task</a>. A
 robot programmed with the <a href="#Gizmo%20Task">Gizmo Task</a> is 
positioned facing a light source. Initially, the gain for the <a href=""
 #gizmo="">Gizmo</a> behavior is set to a low value, while world latency
 is set to a high value. As the simulation runs, the robot moves slowly 
toward the light source, stopping when a specified light intensity is 
reached. If the gain is increased and the simulation restarted, the 
robot will oscillate around the point of desired light intensity.</p>

<a href="#Contents">Contents</a>

</li><li><a name="London Simulation"><h3>London Simulation</h3></a>

<p>The <a href="#London%20Simulation">London Simulation</a> demonstrates
 a weakness of open loop control. A robot programmed with the <a 
href="#London%20Task">London Task</a> is placed in a square-shaped 
corridor. The robot follows the corridor perfectly in <b>Fantasy Mode</b>,
 but will eventually get stuck once <b>Fantasy Mode</b> is switched off 
and noise is added to the system.</p>

<a href="#Contents">Contents</a>


</li></ul>


</li></ul></body></html>